package top.lyjwn.todo.common.redis;

import com.alibaba.fastjson2.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * redis操作实现类
 *
 * @author luoyujie
 */
@Component
public class RedisMap {

    private final Logger log = LoggerFactory.getLogger("error");

    @Autowired
    private RedisTemplate<String, JSONObject> redisTemplate;

    private Map<String, SubRedisObject> subRedisObjectMap = new ConcurrentHashMap<>();

    @Autowired
    private Environment environment;

    private int isRedisConfig = -1;

    private boolean IsRedisConfig() {
        if (isRedisConfig == -1) {
            String host = environment.getProperty("lyjwn.redis.host");
            String port = environment.getProperty("lyjwn.redis.port");
            isRedisConfig = (host == null || "".equals(host) || port == null || "".equals(port)) ? 0 : 1;
        }
        return isRedisConfig == 1;
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(毫秒)
     * @return
     */

    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                if (IsRedisConfig()) {
                    redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);
                } else {
                    subRedisObjectMap.get(key).setExpire(time);
                }
            }
            return true;
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;

        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(毫秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        if (IsRedisConfig()) {
            return redisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
        } else {
            return subRedisObjectMap.get(key).getExpire();
        }
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            if (IsRedisConfig()) {
                return redisTemplate.hasKey(key);
            } else {
                return subRedisObjectMap.get(key) != null;
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;

        }

    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    public void delete(String... key) {
        if (key != null && key.length > 0) {
            if (IsRedisConfig()) {
                if (key.length == 1) {
                    redisTemplate.delete(key[0]);
                } else {
                    Collection<String> objects = Arrays.asList(key);
                    redisTemplate.delete(objects);
                }
            } else {
                for (String s : key) {
                    subRedisObjectMap.remove(s);
                }
            }
        }

    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, JSONObject value) {
        try {
            if (IsRedisConfig()) {
                redisTemplate.opsForValue().set(key, value);
            } else {
                SubRedisObject subRedisObject = new SubRedisObject();
                subRedisObject.setJSONObject(value);
                subRedisObject.setExpire(0);
                subRedisObject.setWriteTime(new Date().getTime());
                subRedisObjectMap.put(key, subRedisObject);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }

    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(毫秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, JSONObject value, long time) {
        try {
            if (time > 0) {
                if (IsRedisConfig()) {
                    redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);
                } else {
                    SubRedisObject subRedisObject = new SubRedisObject();
                    subRedisObject.setJSONObject(value);
                    subRedisObject.setExpire(time);
                    subRedisObject.setWriteTime(new Date().getTime());
                    subRedisObjectMap.put(key, subRedisObject);
                }
                return true;
            } else {
                return set(key, value);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }

    }

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public JSONObject get(String key) {
        if (IsRedisConfig()) {
            return key == null ? null : redisTemplate.opsForValue().get(key);
        } else {
            SubRedisObject subRedisObject = subRedisObjectMap.get(key);
            if (subRedisObject != null && (subRedisObject.getWriteTime() + subRedisObject.getExpire() >= new Date().getTime() || subRedisObject.getExpire() == 0)) {
                return subRedisObject.getJSONObject();
            }
            if (subRedisObject != null && subRedisObject.getWriteTime() + subRedisObject.getExpire() < new Date().getTime()) {
                subRedisObjectMap.remove(key);
            }
            return null;
        }
    }


}
